'''
The mail module of the Life Parser Project.

Author          :                Naresh Pratap Singh
E-Mail          :                MAIL2NARESH@GMAIL.COM
Date            :                Jan 17 2011
Project Advisor :                Prof. Steven Skiena
'''
import errorStrings, debugTrace
import repositoryIface
import eMailParser
import siteConfig
import email
import os, sys
import re
import sentimentPackage

class eMailProcessor:

    repoRoot                        = None
    repoType                        = None
    eMailRegEx                      = '[A-Z0-9-_.%+]+@[A-Z0-9.-]+\.[A-Z]{2,4}'
    stripRegEx                      = '(\nTo:|\nCC:|\nFrom:|\n>)'

    eMailRegExInst                  = None
    stripRegExInst                  = None

    # Enables debug traces for this module if set to True.
    debugEnabled                    = False

    errorStringsInst                = None
    debugTraceInst                  = None

    def __init__(self, repoRoot, repoType, debugEnabled = False):

        self.repoRoot               = repoRoot
        self.repoType               = repoType

        self.debugEnabled           = debugEnabled

        self.eMailRegExInst         = re.compile(self.eMailRegEx, re.IGNORECASE)
    
        self.errorStringsInst       = errorStrings.errorStrings()
        self.debugTraceInst         = debugTrace.debugTrace(self.debugEnabled)


    def processEMails(self, emailId):
        '''
            This function process eMails stored in the repository.
        '''
        try:
            repoInst                    = repositoryIface.repositoryIface(self.repoType, self.repoRoot, self.debugEnabled)
            mailParser                  = eMailParser.eMailParser() 
                
            '''
                Read the stored emails. Following steps are required:
                Connect to DataStore.
                Select user's DataStore.
                Open the output file in analysis directory.
                Enumerate all items.
                Fetch the items in a dictionary.
                Store the required data items.
                Disaonnect from datastore.
                Close the output file.
            '''     
            repoInst.doConnectToDataStore()
            repoInst.doSelectDataStore(emailId)
            
            if os.access(siteConfig.analysisDir, os.F_OK) is False:
                os.mkdir(siteConfig.analysisDir)

            sentFilePath                = os.path.join(siteConfig.analysisDir, emailId + siteConfig.analysisSentSuffix)
            recvFilePath                = os.path.join(siteConfig.analysisDir, emailId + siteConfig.analysisRecvSuffix)
            sentCount                   = 0
            recvCount                   = 0

            hSentFile                   = open(sentFilePath, 'w')
            hRecvFile                   = open(recvFilePath, 'w')
            sentimentInst               = sentimentPackage.sentimentPackage(self.debugEnabled)

            itemList                    = repoInst.doListItems()
            msgDict                     = mailParser.getMessageAsDict(repoInst.doFetchItem(itemList[0]))

            mailCount                   = len(itemList)
            print mailCount
            
            for item in itemList:
                try:
                    msgDict                 = mailParser.getMessageAsDict(repoInst.doFetchItem(item))
                    dirtyDate               = msgDict['Date'][0].replace("=20", ' ')
                    commaIndex              = dirtyDate.find(',')
                    goodDate                = dirtyDate[:commaIndex].strip() + dirtyDate[commaIndex:]
                    sentimentValue          = sentimentInst.computeSentiment(self.stripMessage(msgDict ['Payload']))
                    mailSent                = None
                    
                    if item.find('sent') != -1:
                        mailSent    = True
                        sentCount   = sentCount + 1
                    else:
                        mailSent    = False
                        recvCount   = recvCount + 1

                    if sentimentValue [4] != 0:
                        self.dumpRequiredOutput(hSentFile, hRecvFile, item, emailId, email.utils.parsedate_tz(goodDate), msgDict, sentimentValue, mailSent)
                except KeyError:
                   self.debugTraceInst.doPrintTrace(self.errorStringsInst.getDictKeyMissingError(), sys.exc_info()[2])

                mailCount                   -= 1
           
            self.dumpHeader(hSentFile, hRecvFile, sentCount, recvCount)
            hSentFile.close()
            hRecvFile.close()
        except:
            print sys.exc_info()
        

    def stripMessage(self, message):
        matchObj  = re.search(self.stripRegEx, message, re.IGNORECASE)
        if matchObj is not None:
            return message[:matchObj.start()]
        else:
            return message

    def serializeSentimentTuple(self, sentimentValue):

        mailParser                  = eMailParser.eMailParser() 
        sentimentStr                = ','.join(sentimentValue [1]) + ','
        positiveSentimentStr        = mailParser.doCleanupForFilename(sentimentStr)
        sentimentStr                = ','.join(sentimentValue [3]) + ','
        negativeSentimentStr        = mailParser.doCleanupForFilename(sentimentStr)

        return str(sentimentValue [0]) + '\t' + positiveSentimentStr + '\t' + str(sentimentValue [2]) + '\t' + negativeSentimentStr + '\t' + str(sentimentValue [4])

    def dumpRequiredOutput(self, hSentFile, hRecvFile, item, emailId, dateTime, msgHeader, sentimentValue, mailSent):
        '''
            This function extracts the interesting data from the emails
            and dumps it to output file.
        '''
        mailParser                  = eMailParser.eMailParser() 
        strDateTime                 = '\t' + '%d/%d/%d\t%d:%d:%d'% (dateTime[1], dateTime[2], dateTime[0], dateTime[3], dateTime[4], dateTime[5])
        strSubject                  = '\t' + mailParser.doCleanupForFilename(msgHeader ['Subject'][0])
        strMailKey                  = item
        mailList                    = ''

        if mailSent == True:
            if msgHeader.has_key('To'):
                toList                  = self.eMailRegExInst.findall(msgHeader['To'][0])
                mailList                = '\t' + ' '.join(set(toList)) + '\t' + self.serializeSentimentTuple(sentimentValue)
                hSentFile.write(strMailKey + strDateTime + strSubject + mailList + '\n') 
        else:
            if msgHeader.has_key('From'):
                fromList                = self.eMailRegExInst.findall(msgHeader['From'][0])
                mailList                = '\t' + ' '.join(set(fromList)) + '\t' + self.serializeSentimentTuple(sentimentValue) 
                hRecvFile.write(strMailKey + strDateTime + strSubject + mailList + '\n')

    def dumpHeader(self, hSentFile, hRecvFile, sentCount, recvCount):
        hSentFile.write('HEADER:' + '\t' + str(sentCount) + '\n')
        hRecvFile.write('HEADER:' + '\t' + str(recvCount) + '\n')
